#include "BordWidget.h"
#include <QPainter>
#include <iostream>
#include <QDragEnterEvent>
#include "../model/IllegalBoardException.h"

BordWidget::BordWidget(QWidget * parent) :
	QWidget(parent), manager("/home/tfannes/kolonistenData/tiles.png")
{
	setAcceptDrops(true);
}

BordWidget::~BordWidget()
{
}

void BordWidget::paintEvent(QPaintEvent * event)
{
	QPainter painter(this);

	QVector<board::Tile *> tiles = board.getTiles();

	for(QVector<board::Tile *>::const_iterator i = tiles.begin(); i != tiles.end(); i++)
		painter.drawPixmap(manager.getElementRect((*i)->getHexagon()->getPosition(), size()), manager.getTilePixmap((*i)->getData()));

	if(bTileHoverActivated)
		painter.drawPixmap(manager.getElementRect(hoverTile, size()), manager.getTileOverlay());
}

void BordWidget::dragEnterEvent(QDragEnterEvent * event)
{
	if (event->mimeData()->hasFormat("kolonisten/tile-item"))
		event->accept();
	else event->ignore();
}

void BordWidget::dragLeaveEvent(QDragLeaveEvent * event)
{
	setActiveHover(HoverTypeNothing, HexVector());

	event->accept();
}

void BordWidget::dragMoveEvent(QDragMoveEvent * event)
{
	// get the current position
	structure::HexVector currentPos = manager.getNearestTile(event->pos(), size());

	if(bTileHoverActivated)
	{
		if(currentPos == hoverTile)
		{
			event->accept();
			return;
		}
		else
		{
			QRect previousPos = manager.getElementRect(hoverTile, size());
			update(previousPos);
			hoverTile = currentPos;
		}
	}
	else
	{
		bTileHoverActivated = true;
		hoverTile = currentPos;
	}

	update(manager.getElementRect(hoverTile, size()));
}

void BordWidget::resizeEvent(QResizeEvent * event)
{
	//recalculateMinimumSize();

	event->accept();
}

void BordWidget::dropEvent(QDropEvent * event)
{

	if (event->mimeData()->hasFormat("kolonisten/tile-item"))
		acceptTile(event);

		/*
		QByteArray inArray = event->mimeData()->data("kolonisten/tile-item");
		QDataStream outStream(&inArray, QIODevice::ReadOnly);

		outStream >> tileItem;

		item = new TileItem(tileItem);
		//item->map(tileItem.map);

		update();

		event->setDropAction(Qt::MoveAction);
		event->accept();
	}
	else
	{
		event->ignore();
	}
	*/
}

void BordWidget::recalculateMinimumSize()
{
	QRect rct;

	QVector<board::Tile *> tiles = board.getTiles();

	for(QVector<board::Tile *>::const_iterator i = tiles.begin(); i != tiles.end(); i++)
		rct = rct.united(manager.getElementRect((*i)->getHexagon()->getPosition(), size()));

	QPoint centerPoint = QPoint(size().width()/2, size().height()/2);

	int xBefore = size().width()/2 - rct.left();
	int xAfter = rct.right() - size().width()/2;
	int yBefore = size().height()/2 - rct.top();
	int yAfter = rct.bottom() - size().height()/2;

	setMinimumSize((xBefore > xAfter? xBefore : xAfter)*2, (yBefore > yAfter ? yBefore : yAfter)*2);
}

void BordWidget::acceptTile(QDropEvent * event)
{
	structure::HexVector currentPos = manager.getNearestTile(event->pos(), size());

	QByteArray inArray = event->mimeData()->data("kolonisten/tile-item");
	QDataStream outStream(&inArray, QIODevice::ReadOnly);
	board::TileData data;
	outStream >> data;

	board.setTile(currentPos, data);

	event->accept();

	recalculateMinimumSize();

	update();
}

void BordWidget::setActiveHover(HoverType type, const structure::HexVector & position)
{
	QRect rectToUpdate;

	if(bTileHoverActivated)
		rectToUpdate = rectToUpdate.united(manager.getElementRect(hoverTile, size()));
	else if(bCornerHoverActivated)
		rectToUpdate = rectToUpdate.united(manager.getElementRect(hoverCorner, size()));
	else if(bSideHoverActivated)
		rectToUpdate = rectToUpdate.united(manager.getElementRect(hoverSide, size()));


	bTileHoverActivated = bCornerHoverActivated = bSideHoverActivated = false;

	switch(type)
	{
		case HoverTypeTile:
			bTileHoverActivated = true;
			hoverTile = position;
			break;

		case HoverTypeCorner:
			bCornerHoverActivated = true;
			hoverCorner = position;
			break;

		case HoverTypeSide:
			bSideHoverActivated = true;
			hoverSide = position;
			break;

		default:
			break;
	}

	update(rectToUpdate);
}

BordWidget::HoverType BordWidget::getActiveHover() const
{
	if(bTileHoverActivated)
		return HoverTypeTile;
	else if(bCornerHoverActivated)
		return HoverTypeCorner;
	else if(bSideHoverActivated)
		return HoverTypeSide;
	else
		return HoverTypeNothing;
}

const structure::HexVector & BordWidget::getActiveHoverStructure() const
{
	switch(getActiveHover())
	{
		case HoverTypeTile:
			return hoverTile;

		case HoverTypeCorner:
			return hoverCorner;

		case HoverTypeSide:
			return hoverSide;

		default:
			throw error::IllegalBoardException::CreateInvalidPositionException();
	}
}
